﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;

namespace FasterWPF
{
    public static class BorderExt
    {
        //Due to order of precedence issues, only set Background Color via styles 
        //(so that we can apply MouseOverColor triggers)
        public static void ChangeBackgroundColor(Border button, Brush newColor)
        {
            if (button != null)
            {
                Style style = new Style(typeof(Border), button.Style);

                Setter setter = new Setter();
                setter.Property = Border.BackgroundProperty;
                setter.Value = newColor;
                style.Setters.Add(setter);

                button.Style = style;
            }
        }

        public static void ChangeBackgroundColor(List<Border> buttons, Brush newColor)
        {
            if (buttons != null && buttons.Count > 0)
            {
                Style style = new Style(typeof(Border), buttons[0].Style);

                Setter setter = new Setter();
                setter.Property = Border.BackgroundProperty;
                setter.Value = newColor;
                style.Setters.Add(setter);

                foreach (Border btn in buttons)
                {
                    btn.Style = style;
                }
            }
        }

        public static Border SetMouseOverColorOnBorder(this Border parentBorder, Brush brush)
        {
            Style style = new Style(typeof(Border), parentBorder.Style);
            Trigger t = new Trigger();
            t.Property = Border.IsMouseOverProperty;
            t.Value = true;
            Setter setter = new Setter();
            setter.Property = Border.BackgroundProperty;
            setter.Value = brush;
            t.Setters.Add(setter);

            style.Triggers.Add(t); // Important: add a trigger before applying style
            parentBorder.Style = style;

            return parentBorder;
        }

        public static Border SetMouseOverForeGroundOnBorder(this Border parentBorder, Brush brush)
        {
            Style style = new Style(typeof(Border), parentBorder.Style);
            Trigger t = new Trigger();
            t.Property = Border.IsMouseOverProperty;
            t.Value = true;
            Setter setter = new Setter();
            setter.Property = TextBlock.ForegroundProperty;
            setter.Value = brush;
            t.Setters.Add(setter);

            style.Triggers.Add(t); // Important: add a trigger before applying style
            parentBorder.Style = style;

            return parentBorder;
        }

        public static Border SetMouseOverForeGroundAndRegularForegroundOnBorder(this Border parentBorder, Brush mouseOverForeground, Brush regularForeground)
        {
            Style style = new Style(typeof(Border), parentBorder.Style);
            Trigger t = new Trigger();
            t.Property = Border.IsMouseOverProperty;
            t.Value = true;
            Setter setter = new Setter();
            setter.Property = TextBlock.ForegroundProperty;
            setter.Value = mouseOverForeground;
            t.Setters.Add(setter);

            Setter setter2 = new Setter();
            setter2.Property = TextBlock.ForegroundProperty;
            setter2.Value = regularForeground;
            style.Setters.Add(setter2);

            style.Triggers.Add(t); // Important: add a trigger before applying style
            parentBorder.Style = style;

            return parentBorder;
        }

        public static Border SetMouseOverForeGroundAndRegularForegroundOnBorderWithFonts(this Border parentBorder, Brush mouseOverForeground, Brush regularForeground, FontSettings regularFontSettings, FontSettings mouseOverFontSettings)
        {
            Style style = new Style(typeof(Border), parentBorder.Style);
            Trigger t = new Trigger();
            t.Property = Border.IsMouseOverProperty;
            t.Value = true;

            //MouseOver Properties
            Setter setter = new Setter();
            setter.Property = TextBlock.ForegroundProperty;
            setter.Value = mouseOverForeground;
            t.Setters.Add(setter);

            Setter setter7 = new Setter();
            setter7.Property = TextBlock.FontFamilyProperty;
            setter7.Value = new FontFamily(mouseOverFontSettings.FontFamily);
            t.Setters.Add(setter7);

            Setter setter8 = new Setter();
            setter8.Property = TextBlock.FontSizeProperty;
            setter8.Value = mouseOverFontSettings.FontSize;
            t.Setters.Add(setter8);

            Setter setter9 = new Setter();
            setter9.Property = TextBlock.FontWeightProperty;
            setter9.Value = mouseOverFontSettings.FontWeight;
            t.Setters.Add(setter9);

            Setter setter10 = new Setter();
            setter10.Property = TextBlock.FontStyleProperty;
            setter10.Value = mouseOverFontSettings.FontStyle;
            t.Setters.Add(setter10);
            
            //Regular Properties
            Setter setter2 = new Setter();
            setter2.Property = TextBlock.ForegroundProperty;
            setter2.Value = regularForeground;
            style.Setters.Add(setter2);

            Setter setter3 = new Setter();
            setter3.Property = TextBlock.FontFamilyProperty;
            setter3.Value = new FontFamily(regularFontSettings.FontFamily);
            style.Setters.Add(setter3);

            Setter setter4 = new Setter();
            setter4.Property = TextBlock.FontSizeProperty;
            setter4.Value = regularFontSettings.FontSize;
            style.Setters.Add(setter4);

            Setter setter5 = new Setter();
            setter5.Property = TextBlock.FontWeightProperty;
            setter5.Value = regularFontSettings.FontWeight;
            style.Setters.Add(setter5);

            Setter setter6 = new Setter();
            setter6.Property = TextBlock.FontStyleProperty;
            setter6.Value = regularFontSettings.FontStyle;
            style.Setters.Add(setter6);
            
            style.Triggers.Add(t); // Important: add a trigger before applying style
            parentBorder.Style = style;

            return parentBorder;
        }

        public static Border Initialize(this Border source, double width, double height, ContainerType containerType, Brush borderBrush, Thickness borderThickness, Brush background, CornerRadius cornerRadius, Thickness padding, Thickness margin)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.Width = width;
            source.Height = height;
            source.BorderBrush = borderBrush;
            source.BorderThickness = borderThickness;
            source.CornerRadius = cornerRadius;
            source.Padding = padding;
            source.Margin = margin;

            ChangeBackgroundColor( source, background);

            sharedBorderInitializeCode(source, containerType);

            return source;
        }

        public static Border Initialize(this Border source, double width, double height, ContainerType containerType, Brush borderBrush, Thickness borderThickness, Brush background)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.Width = width;
            source.Height = height;
            source.BorderBrush = borderBrush;
            source.BorderThickness = borderThickness;

            ChangeBackgroundColor(source, background);

            sharedBorderInitializeCode(source, containerType);

            return source;
        }

        public static Border Initialize(this Border source, ContainerType containerType, Brush borderBrush, Thickness borderThickness, Brush background)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.BorderBrush = borderBrush;
            source.BorderThickness = borderThickness;

            ChangeBackgroundColor(source, background);

            sharedBorderInitializeCode(source, containerType);

            return source;
        }

        public static Border Initialize(this Border source, ContainerType containerType, Brush borderBrush, Thickness borderThickness)
        {   
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            source.BorderBrush = borderBrush;
            source.BorderThickness = borderThickness;
            
            sharedBorderInitializeCode(source, containerType);

            return source;
        }
        
        public static Border Initialize(this Border source, ContainerType containerType)
        {   
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            sharedBorderInitializeCode(source, containerType);

            return source;
        }

        //Private Methods
        private static void sharedBorderInitializeCode(Border source, ContainerType containerType)
        {
            source.SetContainerType(containerType);
            IComposite icomp = CompositeTypeHelper.CreateIComposite<Border>(source);
            source.SetIComposite<Border>(icomp);

            BorderParent gbsr = new BorderParent();
            source.StoreSetting<Border>("IParent", gbsr);

            source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border     
            source.StoreSetting<Border>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });
        }                
    }//end of class
}//end of namespace
